<template>
  <div id="cyMultiClickDialog" class="multi-click-dialog">
    <div class="dialog-header">
      <div class="dialog-title">多次点击设置</div>
      <button class="dialog-close" @click="closeDialog">
        <i class="icon-close"></i>
      </button>
    </div>

    <div class="dialog-content">
      <div class="form-group">
        <label class="form-label">点击次数</label>
        <div class="input-group">
          <button class="input-btn" @click="decrementCount">-</button>
          <input
              type="number"
              v-model.number="clickCount"
              min="1"
              max="1000"
              class="form-input"
          >
          <button class="input-btn" @click="incrementCount">+</button>
        </div>
      </div>

      <div class="form-group">
        <label class="form-label">点击间隔 (毫秒)</label>
        <div class="input-group">
          <button class="input-btn" @click="decrementInterval">-</button>
          <input
              type="number"
              v-model.number="clickInterval"
              min="0"
              max="10000"
              class="form-input"
          >
          <button class="input-btn" @click="incrementInterval">+</button>
        </div>
      </div>

      <div class="form-group">
        <label class="form-label">点击类型</label>
        <div class="radio-group">
          <label class="radio-option">
            <input
                type="radio"
                v-model="clickType"
                value="left"
            >
            <span class="radio-custom"></span>
            <span class="radio-label">左键点击</span>
          </label>
          <label class="radio-option">
            <input
                type="radio"
                v-model="clickType"
                value="right"
            >
            <span class="radio-custom"></span>
            <span class="radio-label">右键点击</span>
          </label>
          <label class="radio-option">
            <input
                type="radio"
                v-model="clickType"
                value="double"
            >
            <span class="radio-custom"></span>
            <span class="radio-label">双击</span>
          </label>
        </div>
      </div>

      <div class="preview-section">
        <div class="preview-box" ref="previewBox">
          <div class="preview-text">点击预览区域测试效果</div>
          <div class="click-counter" v-if="previewCount > 0">
            已触发 {{ previewCount }} 次{{ clickType === 'double' ? '双击' : clickType === 'right' ? '右键' : '左键' }}
          </div>
        </div>
      </div>
    </div>

    <div class="dialog-footer">
      <button class="btn secondary" @click="cancelMultiClick">
        <i class="icon-cancel"></i> 取消
      </button>
      <button class="btn primary" @click="startMultiClick">
        <i class="icon-start"></i> 开始点击 ({{ clickCount }}次)
      </button>
    </div>
  </div>
</template>
<script>
import { ref, onMounted, onBeforeUnmount } from 'vue'

export default {
  props: {
    element: {
      type: HTMLElement,
      required: true
    },
    position: {
      type: Object,
      default: () => ({ x: 0, y: 0 })
    }
  },

  emits: ['close', 'start', 'cancel'],

  setup(props, { emit }) {
    // 配置参数
    const clickCount = ref(3)
    const clickInterval = ref(100)
    const clickType = ref('left')
    const previewCount = ref(0)

    // 状态管理
    const isClicking = ref(false)
    const clickTimeouts = ref([])
    const previewBox = ref(null)

    // 数值调整方法
    const incrementCount = () => {
      if (clickCount.value < 1000) clickCount.value++
    }

    const decrementCount = () => {
      if (clickCount.value > 1) clickCount.value--
    }

    const incrementInterval = () => {
      if (clickInterval.value < 10000) clickInterval.value += 50
    }

    const decrementInterval = () => {
      if (clickInterval.value > 0) clickInterval.value -= 50
    }

    // 预览点击效果
    const setupPreview = () => {
      if (!previewBox.value) return

      previewBox.value.addEventListener('click', handlePreviewClick)
      previewBox.value.addEventListener('contextmenu', handlePreviewRightClick)
      previewBox.value.addEventListener('dblclick', handlePreviewDoubleClick)
    }

    const handlePreviewClick = (e) => {
      if (clickType.value === 'left') {
        e.preventDefault()
        previewCount.value++
        setTimeout(() => previewCount.value = 0, 1000)
      }
    }

    const handlePreviewRightClick = (e) => {
      if (clickType.value === 'right') {
        e.preventDefault()
        previewCount.value++
        setTimeout(() => previewCount.value = 0, 1000)
      }
    }

    const handlePreviewDoubleClick = (e) => {
      if (clickType.value === 'double') {
        e.preventDefault()
        previewCount.value++
        setTimeout(() => previewCount.value = 0, 1000)
      }
    }

    // 执行多次点击
    const startMultiClick = () => {
      if (isClicking.value) return

      isClicking.value = true
      props.element.classList.add('multi-click-active')

      // 根据不同类型触发点击
      for (let i = 0; i < clickCount.value; i++) {
        const timeoutId = setTimeout(() => {
          triggerClick(props.element, clickType.value)
        }, i * clickInterval.value)

        clickTimeouts.value.push(timeoutId)
      }

      // 完成后重置
      setTimeout(() => {
        stopMultiClick()
        emit('start', {
          count: clickCount.value,
          interval: clickInterval.value,
          type: clickType.value
        })
      }, clickCount.value * clickInterval.value + 100)
    }

    const triggerClick = (element, type) => {
      if (!element) return

      const rect = element.getBoundingClientRect()
      const x = rect.left + rect.width / 2
      const y = rect.top + rect.height / 2

      // 创建鼠标事件
      let event
      switch (type) {
        case 'right':
          event = new MouseEvent('contextmenu', {
            bubbles: true,
            cancelable: true,
            clientX: x,
            clientY: y,
            button: 2
          })
          break
        case 'double':
          event = new MouseEvent('dblclick', {
            bubbles: true,
            cancelable: true,
            clientX: x,
            clientY: y
          })
          break
        default: // left
          event = new MouseEvent('click', {
            bubbles: true,
            cancelable: true,
            clientX: x,
            clientY: y
          })
      }

      element.dispatchEvent(event)
    }

    const stopMultiClick = () => {
      isClicking.value = false
      clickTimeouts.value.forEach(id => clearTimeout(id))
      clickTimeouts.value = []

      if (props.element) {
        props.element.classList.remove('multi-click-active')
      }
    }

    const cancelMultiClick = () => {
      stopMultiClick()
      emit('cancel')
    }

    const closeDialog = () => {
      stopMultiClick()
      emit('close')
    }

    // 生命周期钩子
    onMounted(() => {
      setupPreview()

      // 设置初始位置
      const dialog = document.getElementById('cyMultiClickDialog')
      if (props.position.x !== 0 || props.position.y !== 0) {
        dialog.style.left = `${props.position.x}px`
        dialog.style.top = `${props.position.y}px`
        dialog.style.transform = 'none'
      }
    })

    onBeforeUnmount(() => {
      stopMultiClick()
      if (previewBox.value) {
        previewBox.value.removeEventListener('click', handlePreviewClick)
        previewBox.value.removeEventListener('contextmenu', handlePreviewRightClick)
        previewBox.value.removeEventListener('dblclick', handlePreviewDoubleClick)
      }
    })

    return {
      clickCount,
      clickInterval,
      clickType,
      previewCount,
      previewBox,
      incrementCount,
      decrementCount,
      incrementInterval,
      decrementInterval,
      startMultiClick,
      cancelMultiClick,
      closeDialog
    }
  }
}
</script>
<style scoped>
.multi-click-dialog {
  --primary-color: #00ff87;
  --secondary-color: #ff1f71;
  --accent-color: #60efff;
  --bg-dark: rgba(10, 20, 30, 0.95);
  --bg-light: rgba(255, 255, 255, 0.1);
  --text-primary: rgba(255, 255, 255, 0.9);
  --text-secondary: rgba(255, 255, 255, 0.7);
  --border-color: rgba(255, 255, 255, 0.2);
  --transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);

  position: fixed;
  width: 400px;
  max-width: 90vw;
  background: var(--bg-dark);
  border-radius: 12px;
  border: 1px solid var(--border-color);
  box-shadow: 0 0 30px rgba(0, 0, 0, 0.5);
  z-index: 10000;
  color: var(--text-primary);
  font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
  backdrop-filter: blur(10px);
  transform: translate(-50%, -50%);
  left: 50%;
  top: 50%;
  overflow: hidden;
}

.dialog-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 15px 20px;
  background: rgba(0, 0, 0, 0.3);
  border-bottom: 1px solid var(--border-color);
}

.dialog-title {
  margin: 0;
  font-size: 1.2rem;
  font-weight: 600;
  background: linear-gradient(135deg, var(--secondary-color) 0%, #a020f0 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.dialog-close {
  background: none;
  border: none;
  color: var(--text-secondary);
  cursor: pointer;
  padding: 5px;
  transition: var(--transition);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
}

.dialog-close:hover {
  background: rgba(255, 255, 255, 0.1);
  color: var(--text-primary);
  transform: rotate(90deg);
}

.dialog-content {
  padding: 20px;
}

.form-group {
  margin-bottom: 20px;
}

.form-label {
  display: block;
  margin-bottom: 8px;
  font-size: 0.95rem;
  color: var(--text-secondary);
}

.input-group {
  display: flex;
  align-items: center;
}

.form-input {
  flex: 1;
  padding: 10px 15px;
  background: var(--bg-light);
  border: 1px solid var(--border-color);
  border-radius: 6px;
  color: var(--text-primary);
  font-family: inherit;
  text-align: center;
  -moz-appearance: textfield;
}

.form-input::-webkit-outer-spin-button,
.form-input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.input-btn {
  width: 40px;
  height: 40px;
  background: var(--bg-light);
  border: 1px solid var(--border-color);
  color: var(--text-primary);
  font-size: 1.2rem;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: var(--transition);
}

.input-btn:first-child {
  border-radius: 6px 0 0 6px;
  border-right: none;
}

.input-btn:last-child {
  border-radius: 0 6px 6px 0;
  border-left: none;
}

.input-btn:hover {
  background: rgba(255, 255, 255, 0.2);
}

.radio-group {
  display: flex;
  gap: 15px;
  margin-top: 10px;
}

.radio-option {
  display: flex;
  align-items: center;
  cursor: pointer;
  font-size: 0.9rem;
}

.radio-option input[type="radio"] {
  position: absolute;
  opacity: 0;
}

.radio-custom {
  width: 16px;
  height: 16px;
  border: 2px solid var(--border-color);
  border-radius: 50%;
  margin-right: 8px;
  position: relative;
  transition: var(--transition);
}

.radio-option input:checked + .radio-custom {
  border-color: var(--primary-color);
}

.radio-option input:checked + .radio-custom::after {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--primary-color);
}

.preview-section {
  margin-top: 30px;
}

.preview-box {
  width: 100%;
  height: 100px;
  background: rgba(0, 0, 0, 0.3);
  border: 2px dashed var(--border-color);
  border-radius: 8px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: var(--transition);
  position: relative;
  overflow: hidden;
}

.preview-box:hover {
  border-color: var(--accent-color);
}

.preview-text {
  font-size: 0.95rem;
  color: var(--text-secondary);
}

.click-counter {
  position: absolute;
  bottom: 10px;
  font-size: 0.85rem;
  color: var(--primary-color);
  animation: fadeIn 0.3s ease-out;
}

@keyframes fadeIn {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

.dialog-footer {
  display: flex;
  justify-content: space-between;
  padding: 15px 20px;
  background: rgba(0, 0, 0, 0.3);
  border-top: 1px solid var(--border-color);
}

.btn {
  padding: 10px 20px;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  font-family: inherit;
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 8px;
  transition: var(--transition);
}

.btn.primary {
  background: linear-gradient(135deg, var(--primary-color) 0%, var(--accent-color) 100%);
  color: #111;
}

.btn.secondary {
  background: var(--bg-light);
  color: var(--text-primary);
}

.btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
}

.icon-close,
.icon-cancel,
.icon-start {
  display: inline-block;
  width: 16px;
  height: 16px;
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
}

.icon-close {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%23ffffff'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M6 18L18 6M6 6l12 12' /%3E%3C/svg%3E");
}

.icon-cancel {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%23ffffff'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M6 18L18 6M6 6l12 12' /%3E%3C/svg%3E");
}

.icon-start {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%23111'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z' /%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M21 12a9 9 0 11-18 0 9 9 0 0118 0z' /%3E%3C/svg%3E");
}

/* 响应式设计 */
@media (max-width: 480px) {
  .radio-group {
    flex-direction: column;
    gap: 8px;
  }

  .dialog-footer {
    flex-direction: column;
    gap: 10px;
  }

  .btn {
    width: 100%;
    justify-content: center;
  }
}

/* 全局高亮样式 */
:global(.multi-click-active) {
  outline: 2px solid var(--secondary-color) !important;
  outline-offset: 2px;
  animation: pulse 1s infinite;
}

@keyframes pulse {
  0% { box-shadow: 0 0 0 0 rgba(255, 31, 113, 0.4); }
  70% { box-shadow: 0 0 0 10px rgba(255, 31, 113, 0); }
  100% { box-shadow: 0 0 0 0 rgba(255, 31, 113, 0); }
}
</style>
